﻿using ProgressTracker.Account.Messages;
using ProgressTracker.Account.Services;
using ProgressTracker.Email.Contracts;
using ProgressTracker.Email.Messages;
using ProgressTracker.WebUI.Infrastructure;
using ProgressTracker.WebUI.Models.Account;
using System.Web.Mvc;

namespace ProgressTracker.WebUI.Controllers
{
    public class AccountController : Controller
    {
        IAccountService _accountService;
        IAuthentication _authentication;
        IEmailService _emailService;

        public AccountController(
            IAccountService accountService, 
            IAuthentication auth,
            IEmailService emailService)
        {
            _accountService = accountService;
            _authentication = auth;
            _emailService = emailService;
        }

        public ActionResult Create()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Create(CreateModel createModel)
        {
            var result = _accountService.CreateAccount(createModel.Email, createModel.Password);

            if (result.ResultCode == AccountResultCode.Success)
            {
                return RedirectToAction("Index", "Home");
            }
            else
            {
                ModelState.AddModelError("CreateError", result.Message);
                return Create();
            }
        }

        public ActionResult Login()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Login(LoginModel loginModel)
        {
            var result = _accountService.Login(loginModel.Email, loginModel.Password);

            if (result.ResultCode == LoginResultCode.Success)
            {
                _authentication.Authenticate(result.User.Email, loginModel.RememberUser);

                if(result.User.MustChangePassword)
                {
                    return RedirectToAction("ChangePassword");
                }

                return RedirectToAction("Index", "Home");
            }
            else if (result.ResultCode == LoginResultCode.AccountDoesNotExist)
            {
                return RedirectToAction("Create");
            }
            else
            {
                ModelState.AddModelError("LoginError", result.Message);
                return Login();
            }
        }

        public ActionResult Logout()
        {
            _authentication.SignOut();

            return View();
        }

        public ActionResult ResetPassword()
        {
            return View();
        }

        [HttpPost]
        public ActionResult ResetPassword(string email)
        {
            if(!_accountService.AccountExists(email))
            {
                //add error and return view
                ModelState.AddModelError("Error", "There is no account registered with the following email address: " + email);

                return View();
            }

            var resetResult = _accountService.ResetPassword(email);

            _emailService.SendEmail(new SendEmailRequest
            {
                Message = "New Password: " + resetResult.NewPassword,
                Sender = Sender.PasswordReset,
                Subject = "New Password",
                ToAddress = email
            });

            TempData["Message"] = "An email containing a temporary password has been sent to: " + email;

            return RedirectToAction("Index", "Home");
        }

        [Authorize]
        public ActionResult ChangePassword()
        {
            return View(new ChangePasswordModel
            {
                UserEmail = User.Identity.Name
            });
        }

        [HttpPost]
        public ActionResult ChangePassword(ChangePasswordModel model)
        {
            var loginResult = _accountService.Login(model.UserEmail, model.OldPassword);

            if(loginResult.ResultCode != LoginResultCode.Success)
            {
                //redirect back to ChangePassword
                ModelState.AddModelError("Error", "Old Password is incorrect.");
                return View();
            }

            var result = _accountService.ChangePassword(model.UserEmail, model.NewPassword);

            TempData["Message"] = "Password Changed Successfully!";

            return RedirectToAction("Index", "Home");
        }
	}
}